package cc.liyinghao.service;

import cc.liyinghao.common.en.MessageType;
import cc.liyinghao.common.dto.NotifyDTO;
import cc.liyinghao.common.pojo.Message;
import cc.liyinghao.security.util.JwtTokenUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.Data;

import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;


@Service
public class WebSocketService {

    @Resource
    private JwtTokenUtil jwtTokenUtil;

    @Data
    public static class WsContent {
        private MessageType type;
        private Object content;
    }

    public static final ConcurrentHashMap<String, Channel> Online_User = new ConcurrentHashMap<>();
    public static final ConcurrentHashMap<Channel, String> Online_Channel = new ConcurrentHashMap<>();

    public void online(Channel channel, String token) {
        try {
            int id = jwtTokenUtil.getUserIdFromToken(token);
            Online_User.put(Integer.toString(id), channel);
            Online_Channel.put(channel, Integer.toString(id));
        } catch (Exception e) {
            channel.close();
        }
    }

    public void offline(Channel channel) {
        String userId = Online_Channel.get(channel);
        if (StrUtil.isNotBlank(userId)) {
            Online_User.remove(userId);
            Online_Channel.remove(channel);
        }
    }

    private void sendMsg(Channel channel, Object msg, MessageType type) {
        WsContent wsContent = new WsContent();
        wsContent.setType(type);
        wsContent.setContent(msg);
        channel.writeAndFlush(new TextWebSocketFrame(JSONUtil.toJsonStr(wsContent)));
    }

    /**
     * 发送消息
     * @param msg 消息内容
     * @param userId 用户id
     * @param targetId 目标用户id
     */
    public void sendMsgToUser(Object msg, String userId, String targetId) {
        //给自己发送消息
        Channel channel = Online_User.get(userId);
        if (channel != null) {
            sendMsg(channel, msg, MessageType.Text);
        }
        //给对方发送消息
        channel = Online_User.get(targetId);
        if (channel != null) {
            sendMsg(channel, msg, MessageType.Text);
        }
    }

    public void sendMsgToGroup(Message message) {
        Online_Channel.forEach((channel, ext) -> {
            sendMsg(channel, message, MessageType.Text);
        });
    }

    public Integer getOnlineNum() {
        return Online_User.size();
    }

    public List<String> getOnlineUser() {
        return new ArrayList<>(Online_User.keySet());
    }

    /**
     * 获取我的在线联系人
     */
    public List<String> getMyOnlineContacts() {
        return new ArrayList<>(Online_User.keySet());
    }

    /**
     * 获取指定id是否在线
     */
    public List<String> getIsOnlineById() {
        return new ArrayList<>(Online_User.keySet());
    }

    /**
     * 发送通知
     * @param notify 通知内容
     */
    public void sendNotifyToGroup(NotifyDTO notify) {
        Online_Channel.forEach((channel, ext) -> {
            sendMsg(channel, notify, MessageType.Notify);
        });
    }


    public void sendVideoToUser(Object msg, String userId) {
        Channel channel = Online_User.get(userId);
        if (channel != null) {
            sendMsg(channel, msg, MessageType.Video);
        }
    }

    public void sendFileToUser(Object msg, String userId) {
        Channel channel = Online_User.get(userId);
        if (channel != null) {
            sendMsg(channel, msg, MessageType.File);
        }
    }
}
